#include <iterator>
#include <iostream>
#include <map>
#include <sstream>
#include <vector>
#include <list>
#include <cstdlib>
#include "lib\functions.h"
using namespace std;

void UpdateWordToLineFrequencyWithMapping(map<string, int> &, vector<list<int> > &, vector<string>);
int NumberLineMatches(list<int>, list<int>);
void FindPair(vector<list<int> >, const map<string, int> &);

int main(int argc, char * argv[])
{
	map<string, int> wordFreq;
	vector<string> fileLines;

	try
	{
		GetMap(argv[1],wordFreq);
		fileLines = GetAllFileLines(argv[1]);
	}
	catch(exception e)
	{
		cout<<"Incorrect arguments passed\n";
		exit(1);
	}

	int word_size=(int) wordFreq.size();
	vector<list<int> > wordToLineMapList(word_size);
	//initialize

	for (int i=0;i<word_size;i++)
	{
		wordToLineMapList[i].push_back(-1);
	}

    UpdateWordToLineFrequencyWithMapping(wordFreq, wordToLineMapList, fileLines);
	FindPair(wordToLineMapList, wordFreq);
}

void UpdateWordToLineFrequencyWithMapping(map<string, int> &wordFreq, vector<list<int> > &wordToLineMapList, vector<string> fileLines)
{
	int num=0;
	for(map<string,int>::iterator wordFreqIter=wordFreq.begin(); wordFreqIter != wordFreq.end(); wordFreqIter++)
	{
		int occurrenceLineNo=0;
		int occurrenceLines=0;
		for(vector<string>::iterator fileLine=fileLines.begin(); fileLine != fileLines.end(); fileLine++)
		{
			stringstream input;
			string token;

			input<<*fileLine;
			while((token=getNextToken<stringstream>(input)) != "")
			{
				if (token==wordFreqIter->first)
				{
					list<int>::iterator temp=wordToLineMapList[num].begin();
					while (*(temp) != -1 )
					{
						temp++;
					}
					*(temp)=occurrenceLineNo;
					temp++;
					wordToLineMapList[num].insert((temp), -1);
					occurrenceLines++;
					break;
				}
			}
			++occurrenceLineNo;
		}
		wordFreqIter->second=occurrenceLines;
		++num;
	}
}


int NumberLineMatches(list<int> iterWord1, list<int> iterWord2)
{
    list<int>::iterator itemp1 = iterWord1.begin();
	list<int>::iterator itemp2 = iterWord2.begin();

    cout<<"value "<<*(itemp1)<<" "<<*(itemp2)<<endl;
	int count=0;
    //min 1 occurrence is there
    while(*(itemp1) != -1 && *(itemp2) != -1)
    {
        if (*(itemp1) == *(itemp2))
        {
			itemp1++;
			itemp2++;
			count++;
        }
        else if (*(itemp1) > (*itemp2))
        {
			itemp2++;
        }
		else if (*(itemp1) < *(itemp2))
		{
			itemp1++;
		}
    }
    return count;
}


/* This function calls NumberLineMatches for every two pair of words in the hashmap */
void FindPair(vector<list<int> > pointslist, const map<string, int> & m)
{
    map<string, int> hmap = m;
    map<string, int>::iterator iter1;
    map<string, int>::iterator start = hmap.begin();

    for(iter1= start; iter1!=hmap.end(); iter1++)
    {
        map<string,int>::iterator iter2=iter1;
        iter2++;

        for(; iter2!=hmap.end(); iter2++)
        {
            cout<<"counts "<<iter1->first<<" "<<iter2->first<<endl;
			cout<<NumberLineMatches (pointslist[distance(start, iter1)], pointslist[distance(start, iter2)])<<" "<<iter1->second<<" "<<iter2->second<<endl;
        }
    }
}
